#include "gen_game_state.h"
#include "build.h"
#include "trn_line.h"

#include "gameflow/ui_popup.h"
#include "admanager/admanager.h"
#include "ui/ui_progress.h"
#include "gameflow/ui_popup.h"
#include "background/bg_editor.h"	// new luabind can't forward define returned types.
#include "background/bg_scene.h"	
#include "application/game_application.h"

#include "dd/dd_man.h"
#include "ui/ui_manager.h"
#include "gameflow/game_flow_manager.h"
#include "script/scripthelper.h"

#include "font/font_manager.h"

			// log
#include "resman/resman.h"				// log

#include "util/timer.h"				
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif

#include <cassert>

using namespace script;

GENGameState::GENGameState(camera::FbCamera*	pCamera, const std::string& UI, const std::string& OnEnter, const std::string& OnExit ) :
	gameflow::UIState(pCamera, UI, OnEnter, OnExit),
	m_bIsPause(false),
	m_pUI(0),
	m_pFrom(0),
	m_pTo(0),
	m_IsDebugging(false),
	m_IsConstantScreenShot(false),
	m_ConstantScreenShotIndex(0),
	m_ToSkipConstantScreenShot(false),
	m_pActivePopup(NULL),
	m_DelayFontRecreate(0)
{	
	 
	//StartLevel("foo.lua");
	//m_pUIPause = m_Panels[0]->GetWidgetByName("pause_play");
	//SetWidgetFunctor("pause_play",UI_DELEGATE(GENGameState, OnButtonPause));
		
	
    

}

GENGameState::~GENGameState()
{
	
	
}


bool	GENGameState::OnEnter()
{

	return gameflow::UIState::OnEnter();
}
bool	GENGameState::OnExit()
{

	return gameflow::UIState::OnExit();
}


void	GENGameState::CachedLoad(const std::string& s)
{
	// are we already trying to transition?
	if (m_pFrom || m_pTo) return;

	m_CachedLoad = s;
	// grab a random intro/outro transition, since we're not changing states
	gameflow::GameFlowManager::Instance().GetTransition().GetTransition("", m_pFrom, m_pTo);
	//if (!m_pGame)	// if there's already a level, use a half transition
	{
		if (!m_CachedLoad.empty())
		{
			LoadFromFile(m_CachedLoad);
		}
		UTIL_SAFE_DELETE(m_pFrom);
	}
}

void	GENGameState::ClearLevel()
{
	
}	

bool	GENGameState::Tick(float dt)
{

	m_GameWorld.Tick(dt);
	return gameflow::UIState::Tick(dt);
} 

bool	GENGameState::PreRender()
{
	
	return UIState::PreRender();
}

bool		GENGameState::PostRender()
{

	m_GameWorld.Render();
	m_GameWorld.RenderDebug();
	TRNLine::Instance().Render();
	return UIState::PostRender();
}



void	GENGameState::MouseScroll(float dt)
{
	
}



void		GENGameState::KeyDown(input::Keyboard::KEY* pKey)
{
	m_GameWorld.KeyDown(pKey);	
}

void		GENGameState::KeyPressed(input::Keyboard::KEY* pKey)
{
	m_GameWorld.KeyPressed(pKey);
	//m_Game.KeyPressed(pKey);	
}


void		GENGameState::MouseMove(const math::Vec2& From, const math::Vec2& To)
{
	if(m_bIsPause)
		return;
	
	m_FocusPoint = To;

}

void	GENGameState::MouseButtonReleased(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{	
	m_GameWorld.MouseButtonReleased( pKey, Pos);
}

void	GENGameState::MouseButtonPressed(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
	m_GameWorld.MouseButtonPressed(pKey, Pos);
}

void	GENGameState::MouseButtonDown(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
	TRNLine::Instance().MouseButtonDown(Pos);
	m_GameWorld.MouseButtonDown(pKey, Pos);
}

void	GENGameState::MouseWheelMove(int WheelInfo, const math::Vec2& Pos)
{
	m_GameWorld.MouseWheelMove( WheelInfo, Pos);
}

GENGameState* GENGameState::GetGame()
{
	gameflow::GameFlowManager&	Game = gameflow::GameFlowManager::Instance();
	GENGameState*	pGame = (GENGameState*)Game.GetStateByName("game");
	assert(pGame && "No valid Game state!");
	return pGame;
}




void	GENGameState::LoadFromFile(const std::string& File)
{
	
	m_CachedLoad.resize(0);	// no longer needed

	//GENSaveGame::Instance().Save(g_pApp->GetSaveFile());
}


void	GENGameState::Save(const std::string& File)
 {
	// if (m_pGame) m_pGame->Save(File); 
 }


static background::BGEditor* GetBGEditor()
{	
/*	gameflow::GameFlowManager&	Game = gameflow::GameFlowManager::Instance();
	GENGameState*	pGame = (GENGameState*)Game.GetStateByName("game");
	GENMapState*	pMap = (GENMapState*)Game.GetStateByName("map");
	gameflow::UIState*	pMenu = (gameflow::UIState*)Game.GetStateByName("MainMenu");


	if (Game.GetCurrentState()==pMap)
	{
		return pMap->GetBG().GetEditor();
	}
	if (Game.GetCurrentState()==pMenu)
	{
		return pMenu->GetBG().GetEditor();
	}
	GENGameWorld*	pWorld = GENGameState::GetWorld();
	if (pWorld)
	{
		if (pWorld->GetBG().GetEditor())	return pWorld->GetBG().GetEditor();
		if (pWorld->GetParallaxBG().GetEditor())	return pWorld->GetParallaxBG().GetEditor();
	}*/
	return background::BGEditor::s_pBGEditor;
}

void GENGameState::Register(LuaPlus::LuaState* _pScript)
{

}


void DELEGATE_CALL		GENGameState::OnButtonPause(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	// this one should be easy to click
	//if(GetLastMouseClickWidget(pWidget) != pWidget)
	//	return;
   

    
}

void			GENGameState::Pause()
{ 
	m_bIsPause = true; 
	if(m_pUIPause)
		m_pUIPause->SetIsVisible(false);
}

void		GENGameState::UnPause()
{ 
	m_bIsPause = false; 
	if(m_pUIPause)
		m_pUIPause->SetIsVisible(true);
}

void		GENGameState::OnLevelCompete()
{
	float AspectRation = (float)( (float)GetGraphics()->GetScreenHeight()  / (float)GetGraphics()->GetScreenWidth());
	std::string File;

	if(AspectRation >= 1.65f)
	{
		File = "ui/5_level_complete.ui";
	}
	else if(AspectRation <= 1.34 )
	{
		File = "ui/ipad_level_complete.ui";  
	}
	else
	{
		File = "ui/level_complete.ui";
	}

    gameflow::UIPopupManager::Instance().StartPopup(File);   		
	
}


void		GENGameState::LoseFocus()
{
	
	m_bIsPause = true;
	gameflow::UIState::LoseFocus();

	m_DelayFontRecreate = 1.0f;
}


void		GENGameState::MouseOnDrag(const math::Vec2& From, const math::Vec2& To) 
{
	m_GameWorld.MouseOnDrag(From, To);
}

void		GENGameState::MouseOnDrop(const math::Vec2& From, const math::Vec2& To)
{
	m_GameWorld.MouseOnDrop(From, To);
}


